package com.mjk.manager.amis.core.controller;


import cn.hutool.core.util.StrUtil;
import com.mjk.common.base.error.BeeError;
import com.mjk.common.base.response.BeeResponse;
import com.mjk.common.core.jdbc.service.idgenerator.IdGenerateType;
import com.mjk.common.core.jdbc.service.plus.idbservice.BeeDBService;
import com.mjk.common.core.jdbc.service.plus.wrap.BeeComplexQueryWrapper;
import com.mjk.common.core.jdbc.service.plus.wrap.BeeQueryWrapper;
import com.mjk.common.util.ObjectUtils;
import com.mjk.common.util.TreeUtils;
import com.mjk.manager.amis.core.dto.AmisCrudDTO;
import com.mjk.manager.amis.core.dto.SessionDetails;
import com.mjk.manager.amis.core.model.*;
import com.mjk.manager.amis.core.utils.SessionHolder;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@RequestMapping("/mamis/sys/role")
@RestController
@Slf4j
public class SysRoleController {
	@Autowired
	SessionHolder contextService;

	@Autowired
    BeeDBService beeDBService;

	@GetMapping("/list")
	public BeeResponse getDeptRoleList(final HttpServletRequest request) {
		// 因为前端传递问题，空白表示为空
		String sysId = contextService.getSystem(request).getId();
		if(ObjectUtils.isEmpty(sysId)){
			return BeeError.TOKEN_IS_EXPRIE.tranceError();
		}
		// 查询数据库
        BeeQueryWrapper wrapper = new BeeQueryWrapper(new SysRole());
		wrapper.eq(SysRole::getOWN_SYS_ID, sysId)
				.eq(SysRole::getDELETED, false);
		List<SysRole> list = beeDBService.findManyByWrapper(wrapper);

		// 构造 amis 要求的数据结构
		final AmisCrudDTO<SysRole> data = new AmisCrudDTO<>();
		data.setItems(list);

		// 返回结果集
		return BeeError.BEE_SUC.tranceError(data);
	}

	@RequestMapping(value = {"","save"})
	public BeeResponse saveDeptRole(final HttpServletRequest request, @RequestBody final SysRole obj) {
		final SessionDetails session = contextService.getSession(request);
		if(session == null){
			return BeeError.TOKEN_IS_EXPRIE.tranceError();
		}
		// 因为前端传递问题，空白表示为空
		if (StrUtil.equals(obj.getDEPT_ID(), "root")) {
			obj.setDEPT_ID(null);
		}
		obj.setUPDATED_BY(session.getCurUser().getId());

		int ret;
		if (ObjectUtils.isNotEmpty(obj.getId())) {
			// update
			// 清除不可更新字段
            BeeQueryWrapper wrapper = new BeeQueryWrapper(obj);
			wrapper.eq(SysRole::getId, obj.getId());
            ret = beeDBService.update(wrapper);
		} else {
			// insert
			obj.setId(IdGenerateType.AUTO_SNOWFLAKE.getGenerator().getId(obj));
			obj.setCREATED_AT(LocalDateTime.now());
			obj.setUPDATED_AT(LocalDateTime.now());
			obj.setDELETED("0");
			obj.setNAME(obj.getDESCR());
			obj.setCREATED_BY(session.getCurUser().getId());
			obj.setOWN_SYS_ID(contextService.getSystem(request).getId());
			ret = beeDBService.save(obj);
		}
		return ret > 0 ? BeeError.BEE_SUC.tranceError() : BeeError.BEE_FAILD.tranceError();
	}

	@RequestMapping(value = {"/{id}","delete/{id}"})
	public BeeResponse delDeptRole(final HttpServletRequest request, @PathVariable("id") String id) {
//        SysRole role = new SysRole();
//        role.setDELETED("1");
        BeeQueryWrapper wrapper = new BeeQueryWrapper(SysRole.class);
		wrapper.eq(SysRole::getId, id);
        int ret = beeDBService.delete(wrapper);
		return ret > 0 ? BeeError.BEE_SUC.tranceError() : BeeError.BEE_FAILD.tranceError();
	}

	@GetMapping("/user/list")
	public BeeResponse getRoleUserList(final HttpServletRequest request,
									   @RequestParam("roleId") String roleId) {
		// 查询数据库
		BeeComplexQueryWrapper wrapper = new BeeComplexQueryWrapper(new PlatUser(), "user");
		wrapper.innerJoin(SysRoleUser.class, "role").on(PlatUser::getId, SysRoleUser::getUSER_ID);
		wrapper.eq(PlatUser::getDELETED, "user", "0");

		wrapper.eq(SysRoleUser::getROLE_ID, "role", roleId);

		List<PlatUser> list = beeDBService.findManyByComplexWrapper(wrapper);

		// 构造 amis 要求的数据结构
		final AmisCrudDTO<PlatUser> data = new AmisCrudDTO<>();
		data.setItems(list);

		// 返回结果集
		return BeeError.BEE_SUC.tranceError(data);
	}

	@GetMapping("/user/candidates")
	public BeeResponse getRoleUserCandidates(final HttpServletRequest request,
											 @RequestParam("roleId") String roleId) {
		// 查询数据库
		BeeQueryWrapper wrapper = new BeeQueryWrapper(new SysRoleUser());
		wrapper.eq(SysRoleUser::getDELETED, "0")
				.eq(SysRoleUser::getROLE_ID, roleId);
		List<SysRoleUser> rus = beeDBService.findManyByWrapper(wrapper);
		BeeQueryWrapper wrapper1 = new BeeQueryWrapper(new PlatUser());
		List<String> ids = rus.stream().map(SysRoleUser::getUSER_ID).collect(Collectors.toList());
		wrapper1.eq(PlatUser::getDELETED, "0").notIn(PlatUser::getId, ids);
		List<PlatUser> users = beeDBService.findManyByWrapper(wrapper1);
		// 构造 amis 要求的数据结构
		final AmisCrudDTO<PlatUser> data = new AmisCrudDTO<>();
		data.setItems(users);

		// 返回结果集
		return BeeError.BEE_SUC.tranceError(data);
	}

	@PostMapping("/user")
	public BeeResponse addRoleUsers(final HttpServletRequest request, @RequestBody Map<String, String> data,
									@RequestParam("roleId") String roleId) {
		final SessionDetails session = contextService.getSession(request);

		String[] ids = data.get("userIds").split(",");

		int ret = 0;
		for (String id : ids) {
			SysRoleUser ru = new SysRoleUser();
			ru.setROLE_ID(roleId);
			ru.setUSER_ID(id);

			ru.setCREATED_BY(session.getCurUser().getId());
			ru.setUPDATED_BY(session.getCurUser().getId());
			ret += beeDBService.save(ru);
		}
		return ret > 0 ? BeeError.BEE_SUC.tranceError() : BeeError.BEE_FAILD.tranceError();
	}

	@DeleteMapping("/user/{userId}")
	public BeeResponse delRoleUser(final HttpServletRequest request, @RequestParam("roleId") String roleId,
								   @PathVariable("userId") String userId) {
		SysRoleUser ru = new SysRoleUser();
		ru.setDELETED("1");
		BeeQueryWrapper wrapper = new BeeQueryWrapper(ru);
		wrapper.eq(SysRoleUser::getROLE_ID, roleId).eq(SysRoleUser::getUSER_ID, userId)
				;
		int ret = beeDBService.update(wrapper);

		return ret > 0 ? BeeError.BEE_SUC.tranceError() : BeeError.BEE_FAILD.tranceError();
	}

	@GetMapping("/menu/option")
	public BeeResponse getRoleMenuOption(final HttpServletRequest request,
										 @RequestParam("roleId") String roleId) {
		BeeComplexQueryWrapper wrapper = new BeeComplexQueryWrapper(new SysMenu(), "menu");
		wrapper.innerJoin(SysRoleMenu.class, "role").on(SysMenu::getId, SysRoleMenu::getMENU_ID);
		wrapper.eq(SysMenu::getDELETED, "menu", "0");

		wrapper.eq(SysRoleMenu::getROLE_ID, "role", roleId);

		List<SysMenu> menuList = beeDBService.findManyByComplexWrapper(wrapper);
		List<SysMenu> menuTree = TreeUtils.list2Tree(menuList, "0", "id", "PID", "children", false);

		List<String> pathList = toOptionPathStream(null, menuTree).collect(Collectors.toList());
		Map<String, String> data = new HashMap<>();
		data.put("menuTree", StrUtil.join(",", pathList));

		return BeeError.BEE_SUC.tranceError(data);
	}

	@PostMapping("/menu/option")
	public BeeResponse saveRoleMenuOption(final HttpServletRequest request, @RequestBody Map<String, String> data,
										  @RequestParam("roleId") String roleId) {
		final SessionDetails session = contextService.getSession(request);

		Set<String> menuIdSet = new HashSet<>();
		Arrays.asList(data.get("menuTree").split(",")).forEach(i -> {
			Arrays.asList(i.split("/")).forEach(menuIdSet::add);
		});
		BeeQueryWrapper wrapper = new BeeQueryWrapper(new SysRoleMenu());
		wrapper.eq(SysRoleMenu::getROLE_ID, roleId);
		beeDBService.delete(wrapper);
		int ret = 0;
		for (String menuId : menuIdSet) {
			SysRoleMenu rm = new SysRoleMenu();
			rm.setROLE_ID(roleId);
			rm.setMENU_ID(menuId);

			rm.setCREATED_BY(session.getCurUser().getId());
			rm.setUPDATED_BY(session.getCurUser().getId());
			ret += beeDBService.save(rm);
		}

		return ret > 0 ? BeeError.BEE_SUC.tranceError() : BeeError.BEE_FAILD.tranceError();
	}

	private <T extends TreeEntity<T>> Stream<String> toOptionPathStream(String prefix,
																		List<SysMenu> tree) {
		return tree.stream().flatMap(i -> {
			StringBuilder builder = new StringBuilder();

			if (StrUtil.isNotBlank(prefix)) {
				builder.append(prefix).append("/");
			}

			builder.append(i.getId());

			List<SysMenu> children = i.getChildren();
			if (children != null && children.size() > 0) {
				return toOptionPathStream(builder.toString(), children);
			} else {
				return Arrays.asList(builder.toString()).stream();
			}
		});
	}
}
